package com.wyfx.blockchain.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wyfx.blockchain.common.response.ResultResponse;
import com.wyfx.blockchain.dao.RocksDao;
import com.wyfx.blockchain.entity.Block;
import com.wyfx.blockchain.entity.dto.IpAndPort;
import com.wyfx.blockchain.service.IBlockService;
import com.wyfx.blockchain.service.ISyncService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * @Description
 * @Auther: wsm
 * @Date: 2020/9/3 14:37
 */
@RestController
@RequestMapping("/block")
@Log4j2
public class BlockController {

    @Autowired
    private IBlockService iBlockService;

    /**
     * @desc 将数据打包成区块
     * @Return org.springframework.http.ResponseEntity
     * @Author wsm
     * @date 2020/9/4 11:37
     */
    @PostMapping("/generateBlock")
    @ApiOperation(value = "生成区块 ")
    public ResultResponse generateBlock(@RequestBody String data) {
        log.info("data :{}", data);
//        List<String> dataList = JSON.parseArray(data, String.class);
        String hash = iBlockService.generateBlock(data);
        return hash != null ? new ResultResponse(HttpServletResponse.SC_OK, hash) : new ResultResponse(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }

    @GetMapping(value = "/first")
    public ResultResponse getFirstBlock() {
        Block firstBlock = iBlockService.getFirstBlock();
        if (firstBlock == null) {
            return new ResultResponse(HttpServletResponse.SC_NO_CONTENT);
        }
        return new ResultResponse(HttpServletResponse.SC_OK, JSONObject.toJSONString(firstBlock));
    }

    @GetMapping(value = "/last")
    public ResultResponse getLastBlock() {
        Block lastBlock = iBlockService.getLastBlock();
        if (lastBlock == null) {
            return new ResultResponse(HttpServletResponse.SC_NO_CONTENT);
        }
        return new ResultResponse(HttpServletResponse.SC_OK, JSONObject.toJSONString(lastBlock));
    }


    @GetMapping("/hash/{hash}")
    public ResultResponse getByBlockHash(@PathVariable String hash) {
        Block block = iBlockService.getBlockByHash(hash);
        if (block == null) {
            return new ResultResponse(HttpServletResponse.SC_NO_CONTENT);
        }
        return new ResultResponse(HttpServletResponse.SC_OK, JSONObject.toJSONString(block));
    }

    /**
     * @param hash 当前区块的hash
     * @desc 测试通过当前区块的hash获取下一块区块数据
     * @Return org.springframework.http.ResponseEntity
     * @Author wsm
     * @date 2020/9/4 14:17
     */
    @GetMapping("/next/{hash}")
    public ResultResponse getNextByCurrentBlockHash(@PathVariable String hash) {
        //模拟一个当前区块
        Block block = new Block();
        block.setHash(hash);
        Block nextBlock = iBlockService.getNextBlock(block);
        return new ResultResponse(HttpServletResponse.SC_OK, JSONObject.toJSONString(nextBlock));
    }


    @Autowired
    private ISyncService iSyncService;

    /**
     * @param ipAndPort 主节点的 ip+端口
     * @desc 处理收到主节点同步区块链数据的请求并主动去主节点同步区块数据
     * @Return com.wyfx.blockchain.common.response.ResultResponse
     * @Author wsm
     * @date 2020/9/8 21:13
     */
    @PostMapping("/sync")
    @ApiOperation(value = "各节点同步区块使用")
    public ResultResponse handleSyncBlockChain(@RequestBody IpAndPort ipAndPort) {
        log.info(" ipAndPort:======={}", ipAndPort);
        boolean b = iSyncService.syncBlockChainData(ipAndPort.getMasterIp(), ipAndPort.getMasterPort());
        log.info("同步区块返回结果：{}", b);
        return new ResultResponse(HttpServletResponse.SC_OK);

    }


    @Autowired
    private RocksDao rocksDao;

    /**
     * @param key
     * @desc 测试通过key 获取rocksDB中对应的数据
     * @Return com.wyfx.blockchain.common.response.ResultResponse
     * @Author wsm
     * @date 2020/9/4 21:24
     */
    @GetMapping("/key/{key}")
    public ResultResponse getRocksByKey(@PathVariable String key) {
        Optional optional = rocksDao.find(key);
        return new ResultResponse(HttpServletResponse.SC_OK, optional.isPresent() ? optional.get().toString() : null);
    }

    @GetMapping("/list/rocksDB")
    public ResultResponse listOfRocksDB() {
        List list = rocksDao.list();
        return new ResultResponse(HttpServletResponse.SC_OK, list);
    }

    @GetMapping("/list/block")
    public ResultResponse listOfBlock() {
        List<Block> blockList = iBlockService.listOfBlock();
        return new ResultResponse(HttpServletResponse.SC_OK, blockList);
    }

}
